<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: Certificate.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: Certificate.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


'use strict';

const crypto = require('crypto');
const fs = require('fs');
const request = require('request');

/**
 * 认证
 **/
class Certificate {
    /**
     * @param {Object} headers http请求的header
     * @param {string} requestBody 请求体
     * @param {string} privateKeyContent 私钥. 用于请求DuerOS参数签名
     **/
    constructor (headers, requestBody, privateKeyContent = '') {
        this.data = requestBody;  
        this.headers = headers;
        this.privateKey = privateKeyContent;
        this.verifyRequestSign = false;
    }

    /**
     * 开启验证请求参数签名，阻止非法请求
     *
     * @return {boolean}
     * @public
     */
    enableVerifyRequestSign() {
        this.verifyRequestSign = true; 
        return this;
    }
    /**
     * 关闭验证请求参数签名
     *
     * @return {boolean}
     * @public
     */
    disableVerifyRequestSign() {
        this.verifyRequestSign = false; 
        return this;
    }

    /**
     * @return promise
     * @private
     */
    _getRequestPublicKey() {
        var _this = this;
        return new Promise(function(resolve, reject){
            var url = _this.headers.signaturecerturl;
            if(!url) {
                reject(); 
            }

            var hash = crypto.createHash('md5');
            var cache = __dirname + '/' + hash.update(url).digest('hex');

            let content = '';
            fs.access(cache, (err) => {
                if(err) {
                    request({
                        url: url,
                        method: 'GET',
                    }, function(error, response, body){
                        let content = body;

                        if(!content) {
                            return reject(); 
                        }

                        fs.writeFile(cache, content, {encoding: "utf8"}, (err) => {
                            if (err) {
                                console.log(err); 
                            } else {
                                resolve(content);
                            }
                        });
                    });
                } else {
                    fs.readFile(cache, {encoding: "utf8"}, (err, data) => {
                        if(err) {
                            console.log(err); 
                        } else {
                            resolve(data); 
                        }
                    });
                }
            });
        });
    }


    /**
     * @desc 验证请求者是否合法
     * @return promise
     * @public
     */
    verifyRequest() {
        var _this = this;
        return new Promise(function(resolve, reject){
            var verify = crypto.createVerify('RSA-SHA1');

            if(!_this.verifyRequestSign) {
                resolve(true);
            }

            _this._getRequestPublicKey().then(function(publicKey){

                if(!publicKey || !_this.data) {
                    reject();
                }

                verify.update(_this.data);
                let isSignatureValid = verify.verify(publicKey.toString(), _this.getRequestSig(), 'base64');
                if(isSignatureValid) {
                    resolve(isSignatureValid);
                }else {

                    reject();
                }

            }, function(){
                reject();
            }); 
        });
    }

    /**
     * @return string
     * @public
     */
    getRequestSig() {
        return this.headers.signature;
    }
}
 
module.exports = Certificate;
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BaseCard.html">BaseCard</a></li><li><a href="BaseDirective.html">BaseDirective</a></li><li><a href="Bot.html">Bot</a></li><li><a href="card_BaseCard.js.html">card/BaseCard.js</a></li><li><a href="Certificate.html">Certificate</a></li><li><a href="directive_BaseDirective.js.html">directive/BaseDirective.js</a></li><li><a href="ImageCard.html">ImageCard</a></li><li><a href="ListCard.html">ListCard</a></li><li><a href="ListCardItem.html">ListCardItem</a></li><li><a href="Nlu.html">Nlu</a></li><li><a href="Play.html">Play</a></li><li><a href="Request.html">Request</a></li><li><a href="Response.html">Response</a></li><li><a href="Session.html">Session</a></li><li><a href="StandardCard.html">StandardCard</a></li><li><a href="Stop.html">Stop</a></li><li><a href="TextCard.html">TextCard</a></li></ul><h3>Namespaces</h3><ul><li><a href="Bot.Card.html">Card</a></li><li><a href="Bot.Directive.html">Directive</a></li><li><a href="Bot.Directive.AudioPlayer.html">AudioPlayer</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Nov 04 2017 11:19:39 GMT+0800 (CST)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
